package com.rfsp.common.util;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.idev.excel.ExcelWriter;
import cn.idev.excel.FastExcel;
import cn.idev.excel.write.metadata.WriteSheet;
import cn.idev.excel.write.metadata.fill.FillConfig;
import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlEngine;
import org.jxls.common.Context;
import org.jxls.expression.JexlExpressionEvaluator;
import org.jxls.transform.Transformer;
import org.jxls.transform.poi.PoiTransformer;
import org.jxls.util.JxlsHelper;

/**
 * The Class ExcelExportHandle.
 * 
 * @author  zhangchao
 * Excel 导出操作类
 */
public class ExcelUtil {


	public static <T> void toExcel(HttpServletResponse httpResponse, Class<T> clazz, List<T> dataList, String filename) throws IOException {

		String outputFileName = URLEncoder.encode(filename, "UTF-8");

		httpResponse.setCharacterEncoding("utf-8");
		httpResponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		httpResponse.setHeader("Content-disposition", "attachment;filename*=utf-8''" + outputFileName + ".xlsx");
		// 写入数据
		//写文件
		toExcel(httpResponse.getOutputStream(), clazz, dataList, filename);
	}

	public static <T> void toExcel(OutputStream os, Class<T> clazz, List<T> dataList, String filename) {
		//写文件
//		FastExcel.write(fileName).sheet("student").head(Student.class).doWrite(students);
		FastExcel.write(os, clazz).sheet(filename).doWrite(dataList);
	}

	public static <T> void toExcel(HttpServletResponse response, List<T> dataList, Map<String, String> dataMap, InputStream template, String sheetname) throws IOException {
		//设置导出文件格式
		response.setHeader("Content-Type", "application/vnd.ms-excel");
		//设置导出文件名称
		response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(sheetname+ ".xlsx", StandardCharsets.UTF_8.toString()));
		//获取模板静态资源
		toExcel(response.getOutputStream(), dataList, dataMap, template, sheetname);
	}

	public static <T> void toExcel(OutputStream os, List<T> dataList, Map<String, String> dataMap, InputStream template, String sheetname) {
		//获取模板静态资源
		try (ExcelWriter excelWriter = FastExcel.write(os).withTemplate(template).build()) {
			//获取模板的sheet1页
			WriteSheet sheet1 = FastExcel.writerSheet(sheetname).build();
			//填充模板第一部分的列表数据
			FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
			excelWriter.fill(dataList, fillConfig, sheet1);
			//填充列表下面的字段
			excelWriter.fill(dataMap, sheet1);


			//sheet2页也可以
				/**    */
//			//获取导出数据源列表
			excelWriter.finish();
		}
	}

	public static void toPdf(File xls, File pdf) throws IOException {
//		FastExcel.
	}

	private static void exportExcel(InputStream is, OutputStream os, Map<String, Object> model) throws IOException{
		Context context = PoiTransformer.createInitialContext();
		if (model != null) {
			for (String key : model.keySet()) {
				context.putVar(key, model.get(key));
			}
		}
		JxlsHelper jxlsHelper = JxlsHelper.getInstance();
		Transformer transformer  = jxlsHelper.createTransformer(is, os);
		//获得配置
		JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator)transformer.getTransformationConfig().getExpressionEvaluator();
		Map<String, Object> functionMap = new HashMap<String, Object>();
		functionMap.put("utils", new JexlUtil());
		JexlBuilder jb = new JexlBuilder();
		jb.namespaces(functionMap);
		JexlEngine je = jb.create();
		evaluator.setJexlEngine(je);
		jxlsHelper.setDeleteTemplateSheet(false);
		//设置静默模式，不报警告
		//evaluator.getJexlEngine().setSilent(true);
		//必须要这个，否者表格函数统计会错乱
		jxlsHelper.setUseFastFormulaProcessor(false);
		jxlsHelper.processTemplate(context, transformer);
	}
	 


	public static void toExcel(Map params,String excelTemplet,String newFileName, HttpServletResponse response,HttpServletRequest request) {

		try( InputStream is = ExcelUtil.class.getResourceAsStream(excelTemplet);
			 OutputStream os = response.getOutputStream()){

			response.reset();
			response.setContentType("application/vnd.ms-excel");
			response.setCharacterEncoding("UTF-8");
        	String userAgent = request.getHeader("USER-AGENT").toLowerCase();
        	if(userAgent.contains("firefox")) {
        		response.setHeader("Content-Disposition","inline;filename="+new String(newFileName.getBytes("utf-8"),"iso8859-1")+".xls");
        	}else {
        		response.setHeader("Content-Disposition","attachment;filename="+java.net.URLEncoder.encode(newFileName,"utf-8")+".xls");
        	}

	        exportExcel(is,os,params);
	        os.flush();
        }catch(Exception e){
        	throw new RuntimeException("文件导出失败！");
        }
	}
	
	public static String saveExcel(Map params, String excelTemplet, String newFilePath) {
		
		try( InputStream is = ExcelUtil.class.getResourceAsStream(excelTemplet);
			 FileOutputStream os = new FileOutputStream(newFilePath)){
	        exportExcel(is,os,params);
        }catch(Exception e){
        	throw new RuntimeException("文件导出失败！");
        }
        return newFilePath;
	}


	public static <T> String toExcelSheets(List<T> mapList, List<String> sheetNames, String excelTemplet, String newFileName, HttpServletResponse response,HttpServletRequest request) {

        try {
			response.reset();
			response.setContentType("application/vnd.ms-excel");
			response.setCharacterEncoding("UTF-8");

			String userAgent = request.getHeader("USER-AGENT").toLowerCase();
			if(userAgent.contains("firefox")) {
				response.setHeader("Content-Disposition","inline;filename="+new String(newFileName.getBytes(StandardCharsets.UTF_8),"iso8859-1")+".xls");
			}else {
				response.setHeader("Content-Disposition","attachment;filename="+java.net.URLEncoder.encode(newFileName,"utf-8")+".xls");
			}

			InputStream is  = ExcelUtil.class.getResourceAsStream(excelTemplet);
			OutputStream os = response.getOutputStream();


			Context context = PoiTransformer.createInitialContext();
			if (mapList != null) {
				context.putVar("pages", mapList);
				context.putVar("sheetNames", sheetNames);
			}
			System.out.println(sheetNames.toString());
			JxlsHelper jxlsHelper = JxlsHelper.getInstance();
			Transformer transformer  = jxlsHelper.createTransformer(is, os);
			//获得配置
			JexlExpressionEvaluator evaluator = (JexlExpressionEvaluator)transformer.getTransformationConfig().getExpressionEvaluator();
			Map<String, Object> functionMap = new HashMap<String, Object>();
			functionMap.put("utils", new JexlUtil());
			JexlBuilder jb = new JexlBuilder();
			jb.namespaces(functionMap);
			JexlEngine je = jb.create();
			evaluator.setJexlEngine(je);
			//设置静默模式，不报警告
			//evaluator.getJexlEngine().setSilent(true);
			//必须要这个，否者表格函数统计会错乱
			jxlsHelper.setDeleteTemplateSheet(true);
			jxlsHelper.setUseFastFormulaProcessor(false);
			jxlsHelper.processTemplate(context, transformer);


			os.flush();
		}catch(Exception e){
			throw new RuntimeException("文件导出失败！");
		}
        return null;
	}


}

class JexlUtil {

	Map<String,Integer> countMap = new HashMap<>(); //用于jxls的foreach循环计数
	public Integer count(String var){
		if (var == null) return null;
		if(countMap.containsKey(var)){
			Integer t = countMap.get(var);
			t++;
			countMap.replace(var,t);
			return t;
		}else{
			countMap.put(var,1);
		}
		return 1;
	}

}